package javaClassExercise.designPatterns.singleton;

/**
 * Created by lomo on 2017/3/26.
 *
 * 单例模式
 *
 */
public class Singleton {
    /* 私有静态变量instance, 防止被引用; instance变量在此处赋值为null, 实现延迟加载 -- 有的类比较大 延迟加载提升性能*/
    private static Singleton instance = null;

    /* 定义私有类型的构造函数(默认为public级别)， 可以防止被实例化new*/
    private Singleton() {}

    /*public访问级别、静态static类型的返回类型为Singleton引用类型的getInstance方法； getInstance方法作用：获取本类实例*/
//    public static Singleton getInstance() {
//        if (instance == null) {
//            return new Singleton();
//        }
//
//        return instance;
//    }
    //第一次改进后的：
    //加了synchronized关键字保证了同步性，只需要在创建时上一次锁，(也避免每次调用该方法时对调用对象上锁)
    //此时，调用的时候是不需要加锁，当instance为null，并创建对象时才需要加锁，
    //问题：此时还是存在问题，当2个线程同时需要调用该方法时，第一个线程访问后，在内存里创建了实例对象，
    // 但是由于JVM的一些优化机制，导致线程2调用Singleton实例时，发现Singleton未被实例，获取不到内存中保存的实例对象，就会报错
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    return new Singleton();
                }
            }
        }

        return instance;
    }

    public Object readResolve() {
        return instance;
    }

//    public static void main(String... args) {
//        System.out.print(Singleton.getInstance().hashCode());
//        System.out.println(instance); //null
//        System.out.println(instance instanceof Singleton); // false
//        Singleton singleton = new Singleton(); //Exception in thread "main" java.lang.NullPointerException, 空指针异常
//        Singleton singleton1 = new  Singleton();
//    }

}

// 当多个线程同时调用该单例类的方法时，对于无保护的这种类，如何改进避免出现异常问题？
class Test {

}